package disk;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import context.ApplicationContext;

/**
 * 磁盘类
 * 
 * @author vincent
 * 
 */
public class Disk {
	/**
	 * 盘块(128个)
	 */
	private Block[] blocks = null;
	/**
	 * 文件分配表(占用第0、1盘块)
	 */
	private FAT fat = null;
	/**
	 * 根目录(占用第2盘块)
	 */
	private Directory rootDir = null;
	/**
	 * 磁盘实例
	 */
	private static Disk disk = null;

	/**
	 * 获取磁盘实例
	 * 
	 * @return
	 */
	public static Disk getInstance() {
		if (Disk.disk == null) {
			Disk.disk = new Disk();
		}
		return Disk.disk;
	}

	/**
	 * 私有构造函数
	 */
	private Disk() {
		// TODO 自动生成的构造函数存根
		init();
	}

	/**
	 * 初始化
	 */
	private void init() {
		blocks = new Block[128]; // 128个盘块
		for (int i = 0; i < blocks.length; i++) {
			blocks[i] = new Block();
		}
		fat = new FAT(new Block[] { blocks[0], blocks[1] });// fat占用2个盘块
		rootDir = new Directory(blocks[2], "/");// 根目录占用1个盘块 路径为"/"

	}

	/**
	 * 获取文件分配表
	 * 
	 * @return
	 */
	public FAT getFat() {
		return fat;
	}

	/**
	 * 获取根目录
	 * 
	 * @return
	 */
	public Directory getRootDir() {
		return rootDir;
	}

	/**
	 * 获取第index个盘块
	 * 
	 * @param index
	 * @return
	 */
	public Block getBlock(int index) {
		return blocks[index];
	}

	/**
	 * 清空盘块内容
	 * 
	 * @param blockIndexes
	 */
	public void clearBlocks(byte[] blockIndexes) {
		for (int i = 0; i < blockIndexes.length; i++) {
			getBlock(blockIndexes[i]).clear();
		}
	}

	/**
	 * 清空盘块内容
	 * 
	 * @param blockIndexes
	 */
	public void clearBlocks(ArrayList<Byte> blockIndexes) {
		for (int i = 0; i < blockIndexes.size(); i++) {
			getBlock(blockIndexes.get(i)).clear();
		}
	}

	/**
	 * 输出指定磁盘的内容
	 */
	public void print(int from, int to) {
		for (int i = from; i <= to; i++) {
			Block block = getBlock(i);
			byte[] bytes = block.getBytes();
			System.out.println("第" + i + "个盘块:");
			for (int j = 0; j < bytes.length; j++) {
				System.out.printf("%5d%5d%5c\n", j, bytes[j], (char) bytes[j]);
			}
		}
	}

	/**
	 * 输出指定磁盘的内容
	 */
	public void print(int to) {
		for (int i = 0; i <= to; i++) {
			Block block = getBlock(i);
			byte[] bytes = block.getBytes();
			System.out.println("第" + i + "个盘块:");
			for (int j = 0; j < bytes.length; j++) {
				System.out.printf("%5d%5d%5c\n", j, bytes[j], (char) bytes[j]);
			}
		}
	}

	/**
	 * 输出整个磁盘的内容
	 */
	public void print() {
		print(128);
	}

	/**
	 * 保存磁盘的数据到本地文件
	 * 
	 * @return
	 * @throws IOException
	 */
	public void saveData(String filePath) throws IOException {
		FileOutputStream outputStream = new FileOutputStream(filePath);
		for (int i = 0; i < 128; i++) {
			byte[] data = getBlock(i).getBytes();
			outputStream.write(data);
		}
		outputStream.close();
	}

	/**
	 * 保存磁盘的数据到本地文件
	 * 
	 * @return
	 * @throws IOException
	 */
	public void saveData() throws IOException {
		saveData(ApplicationContext.getDiskSavePath());
	}

	/**
	 * 从本地文件中加载数据到磁盘
	 * 
	 * @return
	 * @throws IOException
	 */
	public void loadDate(String filePath) throws IOException {
		FileInputStream inputStream = new FileInputStream(filePath);
		for (int i = 0; i < 128; i++) {
			byte[] data = new byte[64];
			inputStream.read(data);
			getBlock(i).setBytes(data);
		}
		inputStream.close();
	}

	/**
	 * 从本地文件中加载数据到磁盘
	 * 
	 * @return
	 * @throws IOException
	 */
	public void loadDate() throws IOException {
		loadDate(ApplicationContext.getDiskSavePath());
	}

}
